using System;
using System.Collections.Generic;
using System.IO;

using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Sustainalytics.ClientDW.DataAccessLayer;
using Sustainalytics.ClientDW.DataAccessLayer.ESGRatings;
using Sustainalytics.Entities.ESGRatings;
using Sustainalytics.ESGRatings.BusinessLogic;
using Sustainalytics.ESGRatings.BusinessLogic.Models;

namespace Sustainalytics.ESGRatings.Service.Tests
{
    using Sustainalytics.DataLayer.EsgRatings;

    [TestClass]
    public class KeyESGIssuesManagementTests
    {
        private static Mock<IEsgInputFileRepository> _mockFile;
        private static IKeyESGIssuesManagement _management;
        private static Mock<IKeyEsgIssuesRepository> _mockKeyEsgIssueRepository;
        private static readonly string _connStringDw = "mongodb://localhost:27017/ClientDW";

        private static EsgInputFileComplete GetTestValidXExcelFile()
        {
            return GetExcelFileData("ESGIssuesManagementTemplate March 5th.xlsx");
        }

        private static EsgInputFileComplete GetExcelFileData(string fileName)
        {
            var bytes =
                File.ReadAllBytes(Path.Combine(Directory.GetCurrentDirectory(),
                    fileName));
            return new EsgInputFileComplete()
            {
                Content = bytes,
                ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
                CreationTimestamp = DateTime.Now,
                FileName = fileName,
                Id = new Guid(),
                Name = "EsgTemplateNew",
                Type = EsgInputFileType.KeyESGIssues
            };
        }

        private static EsgInputFileComplete GetTestInvalidExcelFile()
        {
            return GetExcelFileData("Invalid_ESGIssuesManagementTemplate March 5th.xlsx");
        }

        private static EsgInputFileComplete GetTestInvalidTypeBExcelFile()
        {
            return GetExcelFileData("Invalid_TypeB_Indicator_ESGIssuesManagementTemplate March 5th.xlsx");
        }



        [ClassInitialize]
        public static void PrepareUnitTest(TestContext context)
        {
            _mockFile = new Mock<IEsgInputFileRepository>();
            _mockFile.Setup(
                a => a.ListLatestUnprocessedFiles(It.Is<EsgInputFileType>(c => c == EsgInputFileType.KeyESGIssues)))
                .Returns(new List<EsgInputFileComplete>() {GetTestValidXExcelFile()});

            
            var clientDwRepository = ClientDwRepository.GetInstance(_connStringDw);
            _mockKeyEsgIssueRepository=new Mock<IKeyEsgIssuesRepository>();
            _management = KeyEsgIssuesManagement.GetInstance(clientDwRepository, _mockFile.Object,
                _mockKeyEsgIssueRepository.Object);
        }

        [TestMethod]
        public void LoadKeyESGIssuesForProcessing_ShouldReturnNoErrors_New_Excel_With_2_IndicatorTypes()
        {
            var file = GetTestValidXExcelFile();
            var output = _management.LoadKeyESGIssuesForProcessing(file.FileName, file.Content, file.ContentType);
            var expected = new FileUploadLogs(){Errors = string.Empty};
            Assert.AreEqual(expected,output);
        }


        [TestMethod]
        public void LoadKeyESGIssuesForProcessing_ShouldReturnErrors_CurrentExcel_Does_Not_Respect_The_Template()
        {
            var file = GetTestInvalidExcelFile();
            var output = _management.LoadKeyESGIssuesForProcessing(file.Name, file.Content, file.ContentType);
            var expected = new FileUploadLogs()
            {
                Errors =
                    "The excel file sent for processing does not have the expected sheets name format:Indicators A,Indicators B,Values,Events.The file uploaded has the following format:RpIndicators,Values,Events"
            };
            Assert.AreEqual(expected,output);
        }


        [TestMethod]
        public void LoadKeyESGIssuesForProessing_ShouldReturnErrors_TypeAIndicatorHasSomeErrors()
        {
            var file = GetTestInvalidTypeBExcelFile();
            var output = _management.LoadKeyESGIssuesForProcessing(file.Name, file.Content, file.ContentType);
            Assert.IsTrue(output.Errors.Length>0);
        }
    }
}
